#ifndef GS_ICONTEXT_H
#define GS_ICONTEXT_H

#include "Config.h"
#include "IReferenced.h"

namespace Gs
{
	class IString;
	class IObject;

	// Represents a GorillaScript runtime context.
	class GS_EXPIMP IContext : public IReferenced
	{
	protected:
		// Destroys the instance.
		virtual ~IContext() = 0;

	public:
		// Creates an unreferenced object.
		virtual IObject *CreateObject() = 0;

		// Creates an unreferenced string.
		virtual IString *CreateString(const char *str) = 0;

		// Compiles a script into a function on the stack.
		virtual void CompileScript(const char *script, const char *sourceName = "script") = 0;

		// Compiles a script into a function on the stack using a file.
		virtual void CompileScriptFromFile(const char *filename) = 0;

		// Calls the function on the stack. The function should be pushed before arguments.
		virtual void Call(int arguments) = 0;

		// Gets a pointer to the global object.
		virtual IObject *GetGlobalObject() const = 0;

		// Pops and assigns the value at the top of the stack to a name in the global object.
		virtual void SetGlobal(const char *name) = 0;

		// Pops and assigns the value at the top of the stack to a name in the global object.
		virtual void SetGlobal(IString *name) = 0;

		// Pushes a global value onto the stack.
		virtual void PushGlobal(const char *name) = 0;

		// Pushes a global value onto the stack.
		virtual void PushGlobal(IString *name) = 0;

		// Gets the relative index to the top value on the stack.
		virtual int Top() const = 0;

		// Gets the value at the specified index in the stack.
		virtual IValue *ValueAt(int index = -1) const = 0;

		// Pops the top value off the stack.
		virtual void Pop() = 0;

		// Pushes a nil value onto the stack.
		virtual void Push() = 0;

		// Pushes an integer onto the stack.
		virtual void Push(int i) = 0;

		// Pushes a float onto the stack.
		virtual void Push(float f) = 0;

		// Pushes a string onto the stack.
		virtual void Push(const char *s) = 0;

		// Pushes a string onto the stack.
		virtual void Push(IString *s) = 0;

		// Pushes an object onto the stack.
		virtual void Push(IObject *o) = 0;

		// Pushes a native function onto the stack.
		virtual void Push(NativeFunction f) = 0;

		// Pushes a user pointer onto the stack.
		virtual void Push(UserPointer up) = 0;

		// Pushes a value onto the stack.
		virtual void Push(IValue *v) = 0;
	};

	// Defines a Reference<IObject> type.
	typedef Reference<IContext> IContextRef;

	// Creates a new context.
	GS_EXPIMP IContext *GS_API CreateContext();
}

#endif
